#ifndef __EPSILON__DEBUG_H__
#define __EPSILON__DEBUG_H__

#include "system.h"

// ANSI/Wide string manipulation...
#include "strings.h"

#ifdef _DEBUG
#define DEBUG
#endif

// A BreakPoint macro
#ifdef DEBUG
# ifdef _MSC_VER
#  define BreakPoint() _asm { int 3 }
# else
#  define BreakPoint() asm (" int $3");
# endif
#else
# define BreakPoint()
#endif

/// Default assert macro...
#include <assert.h>

#ifdef Assert
#undef Assert
//#pragma message ("Undefining previous Assert macro...")
#endif

/// Custom defined Assert(condition,message) macro
#ifdef DEBUG

  EPSILON_API bool eCustomAssertFunction ( bool   expression,
		  			   TCHAR* expression_str,
                                           TCHAR* description,
                                           int    lineNumber,
                                           TCHAR* filename );

  #define Assert(expression, description)                                   \
    if (eCustomAssertFunction((int)(expression),                            \
			      _T (#expression),                             \
			                         (description), __LINE__,   \
                                                            _T (__FILE__))) \
      { BreakPoint () }  /// This will cause the debugger to break here

#else
#define Assert(expression, description)
#endif

//
// UNIX equiv. for OutputDebugString
//
#ifndef WIN32
static
void
OutputDebugString (const TCHAR* szOutString)
{
  _ftprintf (stderr, _T ("%s\n"), szOutString);
}
#endif

#include "types.h"

#define E_MB_OK                0x00L
#define E_MB_OKCANCEL          0x01L
#define E_MB_ABORTRETRYIGNORE  0x02L
#define E_MB_YESNOCANCEL       0x03L
#define E_MB_YESNO             0x04L
#define E_MB_RETRYCANCEL       0x05L
#
#define E_MB_APPLMODAL         0x00000L
#define E_MB_SYSTEMMODAL       0x01000L
#define E_MB_TASKMODAL         0x02000L
#
#define E_IDOK                 1
#define E_IDCANCEL             2
#define E_IDABORT              3
#define E_IDRETRY              4
#define E_IDIGNORE             5
#define E_IDYES                6
#define E_IDNO                 7
#define E_IDCLOSE              8
#define E_IDHELP               9
#
#define E_MB_ICONHAND          0x010L
#define E_MB_ICONQUESTION      0x020L
#define E_MB_ICONEXCLAMATION   0x030L
#define E_MB_ICONASTERISK      0x040L
#
#define E_MB_ICONWARNING       E_MB_ICONEXCLAMATION
#define E_MB_ICONERROR         E_MB_ICONHAND

// Encapsulates Win32 MessageBeep
EPSILON_API int __cdecl eMesageBeep   (UINT uFlags = 0xFFFFFFFF);

// Message Box given an arbitrary caption/text
EPSILON_API int __cdecl eMessageBox   (const TCHAR* szText);
EPSILON_API int __cdecl eMessageBoxEx (const TCHAR* szCaption, const TCHAR* szText, UINT uFlags = E_MB_OK);

// Message Box for formatted text (printf-like behaviour)
EPSILON_API int __cdecl eMessageBoxF   (const TCHAR* szFormat, ...);
EPSILON_API int __cdecl eMessageBoxExF (const TCHAR* szCaption, UINT uFlags, const TCHAR* szFormat, ...);


#include "errors.h"

/** 
 * A special singleton object that handles engine debugging.
 *
 */
class eDebug {
public:
           eDebug (void);
  virtual ~eDebug (void);

  const eErrorCode& GetLastError (void) {
    return last_error;
  };

//protected:
  /// Sets a new error and returns any previous error
  eErrorCode SetLastErrorEx (eErrorCode err) {
    eErrorCode old = last_error;
    last_error     = err;

//    BreakPoint ();

    return old;
  };

  /// Sets a new error
  void SetLastError (eErrorCode err) {
    last_error = err;

//    BreakPoint ();
  }

private:
  eErrorCode last_error;
  FILE*      DEV_NULL;
};

#endif /* __EPSILON__DEBUG_H__ */
